/**
 * @BelongsProject: hmall-micro
 * @BelongsPackage: com.hmall.search
 * @Author: 王明天
 * @CreateTime: 2025/2/15 19:40
 * @Description: MyTestClass
 */
package com.hmall.search;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.hmall.common.utils.CollUtils;
import com.hmall.search.domain.po.ItemDoc;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;


@SpringBootTest
public class MyTestClass {

    @Autowired
    private RestHighLevelClient esClient;

    private static SearchRequest searchRequest;

    @BeforeEach
    public void initSearchRequest() {
            searchRequest = new SearchRequest("items");
    }


    @Test
    public void QuertTest() throws Exception {

//        SearchRequest searchRequest = new SearchRequest("items");

        //构建查询条件
        //查询所有 ,相当于DSL中的match_all
//        searchRequest.source().query(QueryBuilders.matchAllQuery());

        //查询包含指定词组的数据(自己不会会分词)，相当于DSL中的term
        searchRequest.source().query(QueryBuilders.termQuery("name", "小米"));

        //查询包含指定词组的数据(自己会分词)，相当于DSL中的match
//        searchRequest.source().query(QueryBuilders.matchQuery("name","小米手机"));

        //查询指定范围的数据，相当于DSL中的range
//        searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(1000).lte(2000));

        //组合条件查询数据，相当于DSL中的bool
/*        searchRequest.source().query(QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("name", "小米手机"))
                .filter(QueryBuilders.rangeQuery("price").gte(1000).lte(2000)));*/

        //排序
        searchRequest.source().sort("price", SortOrder.DESC);

        //分页
        searchRequest.source().from(0);
        searchRequest.source().size(5);

        //执行查询
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);

        //查询到的总记录数
        System.out.println("查询到的总记录数为：" + searchResponse.getHits().getTotalHits().value);

        //查询到的商品信息
        SearchHit[] hits = searchResponse.getHits().getHits();

        //遍历数组
        for (SearchHit hit : hits) {

            //得到的是JSON字符串
            String jsonStr = hit.getSourceAsString();

            //JSON反序列化
            ItemDoc itemDoc = JSONUtil.toBean(jsonStr, ItemDoc.class);

            System.out.println(itemDoc);
        }
    }


    @Test
    public void HighLightQueryTest() throws Exception {

//        SearchRequest searchRequest = new SearchRequest("items");

        //构建查询条件
        //查询包含指定词组的数据(自己不会会分词)，相当于DSL中的term
        searchRequest.source().query(QueryBuilders.termQuery("name", "小米"));

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").preTags("<span style='color:red'>").postTags("</span>");
        searchRequest.source().highlighter(highlightBuilder);

        //执行查询
        SearchResponse searchResponse = esClient.search(searchRequest, RequestOptions.DEFAULT);

        //查询到的总记录数
        System.out.println("查询到的总记录数为：" + searchResponse.getHits().getTotalHits().value);

        //查询到的商品信息
        SearchHit[] hits = searchResponse.getHits().getHits();

        //遍历数组
        for (SearchHit hit : hits) {

            //得到的是JSON字符串
            String jsonStr = hit.getSourceAsString();

            //JSON反序列化
            ItemDoc itemDoc = JSONUtil.toBean(jsonStr, ItemDoc.class);

            //处理高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();

            if (CollUtils.isNotEmpty(highlightFields)) {

                HighlightField names = highlightFields.get("name");

                if (ObjectUtil.isNotEmpty(names)) {

                    Text[] fragments = names.getFragments();

                    if (fragments != null || fragments.length > 0) {

                        itemDoc.setName(fragments[0].toString());
                    }
                }
            }

            System.out.println(itemDoc);
        }
    }


    @Test
    public void AggQueryTest() throws Exception {

//        SearchRequest searchRequest = new SearchRequest("items");

        //构建聚和条件
        searchRequest.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(20));
        searchRequest.source().aggregation(AggregationBuilders.terms("categoryAgg").field("category").size(20));
        SearchResponse search = esClient.search(searchRequest, RequestOptions.DEFAULT);
        Aggregations aggregations = search.getAggregations();

        Terms brandAggTerms = aggregations.get("brandAgg");
        List<? extends Terms.Bucket> buckets = brandAggTerms.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println(bucket.getKey());
            System.out.println(bucket.getDocCount());

        }

        Terms categoryAggTerms = aggregations.get("categoryAgg");
        List<? extends Terms.Bucket> buckets1 = categoryAggTerms.getBuckets();
        for (Terms.Bucket bucket : buckets1) {
            System.out.println(bucket.getKey());
            System.out.println(bucket.getDocCount());

        }
    }


}
